package com.solution.service;

import java.util.Iterator;
import java.util.List;

import javax.ejb.EJBException;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;

import org.apache.log4j.Logger;
import org.jboss.annotation.ejb.RemoteBinding;

import com.solution.constant.ErrorMessages;
import com.solution.constant.UserManagementErrorMessage;
import com.solution.dao.DAOFactory;
import com.solution.dao.UserPermissionTypeDAO;
import com.solution.dao.UserRolePermissionDAO;
import com.solution.dao.UserRoleTypeDAO;
import com.solution.exception.DAOException;
import com.solution.exception.ServiceBeanException;
import com.solution.model.UserPermissionType;
import com.solution.model.UserRolePermission;
import com.solution.model.UserRolePermissionId;
import com.solution.model.UserRoleType;
import com.solution.util.SearchVO;

/**
 * This class exposes all the services for creation, update, read and
 * deletion of Role.
 *
 *
 */
@Stateless
@Remote(UserRolePermissionService.class)
@RemoteBinding(jndiBinding="UserRolePermissionService")
@TransactionManagement(TransactionManagementType.CONTAINER)
public class UserRolePermissionServiceImpl {
	
	/**
	 * DAO instance.
	 */
	private UserRolePermissionDAO userRolePermissionDao = (UserRolePermissionDAO)DAOFactory.getDAOInstance(UserRolePermissionDAO.class.getName());
	private UserRoleTypeDAO userRoleTypeDao = (UserRoleTypeDAO)DAOFactory.getDAOInstance(UserRoleTypeDAO.class.getName());
	private UserPermissionTypeDAO userPermissionTypeDao = (UserPermissionTypeDAO)DAOFactory.getDAOInstance(UserPermissionTypeDAO.class.getName());

	/**
	 * Logger instance.
	 */
	private Logger log = Logger.getLogger(UserRolePermissionServiceImpl.class.getName());
	
	/**
	 * This service creates the Role entry in the database after performing
	 * required business logic.
	 * @param userRoleTye
	 * @param permissionIDs
	 * @return
	 * @throws ServiceBeanException
	 */
	public UserRoleType create(UserRoleType userRoleType,String permissionIDs[]) throws ServiceBeanException{
		log.debug("Entering :: UserRolePermissionServiceImpl:create()");
		try{
			// check for the mandatory parameters.
			if(userRoleType!= null && userRoleType.checkForMandatoryParameters() != null && userRoleType.checkForMandatoryParameters().size() > 0){
				String errorMsg = ErrorMessages.MANDATORY_PARAMETER_MISSING_EXCEPTION;
				Iterator<String> iter = userRoleType.checkForMandatoryParameters().iterator();
				while(iter.hasNext()){
					errorMsg = errorMsg+", "+iter.next();
				}
				throw new ServiceBeanException(errorMsg);
			}
			boolean isRoleUnique = userRoleTypeDao.verifyUnique("name",userRoleType.getName(),null);
			if(!isRoleUnique)
			{
				userRoleType.setRoleExist(!isRoleUnique);
				return userRoleType;
			}
			userRoleType = userRoleTypeDao.create(userRoleType);
			UserRolePermission userRolePermission = null;
			if(permissionIDs != null){
				for(int i= 0;i<permissionIDs.length; i++){
					userRolePermission = new UserRolePermission();
					UserRolePermissionId userRolePermissionId = new UserRolePermissionId();
					userRolePermissionId.setUserPermissionTypeId(Long.valueOf(permissionIDs[i]));
					userRolePermissionId.setUserRoleTypeId(userRoleType.getId());					
					userRolePermission.setId(userRolePermissionId);
					userRolePermissionDao.create(userRolePermission);
				}
			}
			log.info("The new Role created with ID : "+userRoleType.getId());
			log.debug("Exiting :: UserRolePermissionServiceImpl:create()");
			return userRoleType;
		}
		catch(DAOException ex){
			log.error(UserManagementErrorMessage.ROLE_CREATE_EXCEPTION, ex);
			throw new EJBException(ex);
		}
	}
	
	/**
	 * This service updates the Role entry in the database after performing
	 * required business logic.
	 * @param userRoleType
	 * @return
	 * @throws ServiceBeanException
	 */
	public UserRoleType update(UserRoleType userRoleType,String permission[]) throws ServiceBeanException{
		log.debug("Entering :: UserRolePermissionServiceImpl:update()");
		try{
			// check for the mandatory parameters.
			if(userRoleType != null && userRoleType.checkForMandatoryParameters() != null && userRoleType.checkForMandatoryParameters().size() > 0){
				String errorMsg = ErrorMessages.MANDATORY_PARAMETER_MISSING_EXCEPTION;
				Iterator<String> iter = userRoleType.checkForMandatoryParameters().iterator();
				while(iter.hasNext()){
					errorMsg = errorMsg+", "+iter.next();
				}
				throw new ServiceBeanException(errorMsg);
			}
			// Update the entry in database.
			userRoleType = userRoleTypeDao.update(userRoleType);
			userRolePermissionDao.deleteAllPermissionForRole(userRoleType.getId());
			UserRolePermission userRolePermission;
			for (int i=0;permission!=null && i<permission.length;i++){
				userRolePermission = new UserRolePermission();			

				UserRolePermissionId userRolePermissionId = new UserRolePermissionId();
				userRolePermissionId.setUserRoleTypeId(userRoleType.getId());
				userRolePermissionId.setUserPermissionTypeId(Long.parseLong(permission[i]));				
				userRolePermission.setId(userRolePermissionId);
				userRolePermission.setUserRoleType(userRoleType);
				
				UserPermissionType userPermissionType = new UserPermissionType() ;
				userPermissionType.setId(Long.parseLong(permission[i]));
				userRolePermission.setUserPermissionType(userPermissionType);
				userRolePermissionDao.create(userRolePermission);				
			}
			log.info("The Role updated with ID : "+userRoleType.getId());
			log.debug("Exiting :: UserRolePermissionServiceImpl:update()");
			return userRoleType;
		}
		catch(DAOException ex){
			log.error(UserManagementErrorMessage.ROLE_UPDATE_EXCEPTION, ex);
			throw new EJBException(ex);
		}
	}
	
	/**
	 * This service reads a Role from database based on the primary
	 * key.
	 * @param userRoleTypeID
	 * @return
	 * @throws ServiceBeanException
	 */
	public UserRoleType read(Long userRoleTypeId) throws ServiceBeanException{
		try{
			log.debug("Inside :: UserRolePermissionServiceImpl:read()");
			if(userRoleTypeId != null){
				return userRoleTypeDao.read(userRoleTypeId);
			}
			else{
				throw new ServiceBeanException(ErrorMessages.MANDATORY_PARAMETER_MISSING_EXCEPTION+" userRoleTypeId");
			}
		}
		catch(DAOException ex){
			log.error(UserManagementErrorMessage.ROLE_READ_EXCEPTION, ex);
			throw new EJBException(ex);
		}
	}
	
	/**
	 * This service deletes a Role from database based on the primary
	 * key.
	 * @param userRoleTypeId
	 * @throws ServiceBeanException
	 */
	public void delete(Long userRoleTypeId) throws ServiceBeanException{
		try{
			log.debug("Inside :: UserRolePermissionServiceImpl:delete()");
			userRoleTypeDao.delete(userRoleTypeId);
		}
		catch(DAOException ex){
			log.error(UserManagementErrorMessage.ROLE_READ_EXCEPTION, ex);
			throw new EJBException(ex);
		}
	}	
	
	/**
	 * Get complete list of permissions
	 * @return
	 * @throws ServiceBeanException
	 */
	public List<UserPermissionType> getPermissionList()	throws ServiceBeanException {
		try{
			log.debug("Inside :: UserRolePermissionServiceImpl:getPermissionList()");
			SearchVO searchVO = new SearchVO();
			searchVO.addOrderAscending("groupName");
			return userPermissionTypeDao.search(searchVO);
		}
		catch(DAOException ex){
			log.error(UserManagementErrorMessage.ROLE_READ_EXCEPTION, ex);
			throw new EJBException(ex);
		}		
	}
	
	/**
	 * get List of roles
	 * @param roleName
	 * @return
	 * @throws ServiceBeanException
	 */
	public List<UserRoleType> getUserRolesList(String roleName) throws ServiceBeanException {
		try{
			log.debug("Inside :: UserRolePermissionServiceImpl:getUserRolesList()");
			if(roleName != null){
				SearchVO searchVO = new  SearchVO();
				searchVO.addLikeCondition("name",roleName);			
				return userRoleTypeDao.search(searchVO);
			}
			else{
				throw new ServiceBeanException(ErrorMessages.MANDATORY_PARAMETER_MISSING_EXCEPTION+" roleName");
			}
		}
		catch(DAOException ex){
			log.error(UserManagementErrorMessage.ROLE_READ_EXCEPTION, ex);
			throw new EJBException(ex);
		}	
	}
	
	/**
	 * get Permission List of Roles
	 * @param roleID
	 * @return
	 * @throws ServiceBeanException
	 */
	public List<UserRolePermission> getRolePermissionList(Long roleID) throws ServiceBeanException {
		try{
			log.debug("Inside :: UserRolePermissionServiceImpl:getRolePermissionList()");
			if(roleID != null){
				SearchVO searchVO = new SearchVO();
				searchVO.addEqualsCondition("userRoleType.id",roleID);
				return userRolePermissionDao.search(searchVO);
			}
			else{
				throw new ServiceBeanException(ErrorMessages.MANDATORY_PARAMETER_MISSING_EXCEPTION+" roleID");
			}
		}
		catch(DAOException ex){
			log.error(UserManagementErrorMessage.ROLE_READ_EXCEPTION, ex);
			throw new EJBException(ex);
		}		
	}

	/**
	 * get list of permissions for user
	 * @param userID
	 * @return
	 * @throws ServiceBeanException
	 */
	public List<UserPermissionType> getPermissionListByUserId(Long userID) throws ServiceBeanException {
		try{
			log.debug("Inside :: UserRolePermissionServiceImpl:getPermissionListByUserId()");
			if(userID != null){
				return userPermissionTypeDao.getPermissionListByUserId(userID);
			}
			else{
				throw new ServiceBeanException(ErrorMessages.MANDATORY_PARAMETER_MISSING_EXCEPTION+" userID");
			}
		}
		catch(DAOException ex){
			log.error(UserManagementErrorMessage.ROLE_READ_EXCEPTION, ex);
			throw new EJBException(ex);
		}		
	}
	
	public UserPermissionType createUserPermissionType(UserPermissionType userPermissionType) throws ServiceBeanException{
		try{
			// Perform business validations.
			// check for the mandatory parameters.
			if(userPermissionType.checkForMandatoryParameters() != null && userPermissionType.checkForMandatoryParameters().size() > 0){
				String errorMsg = ErrorMessages.MANDATORY_PARAMETER_MISSING_EXCEPTION;
				Iterator<String> iter = userPermissionType.checkForMandatoryParameters().iterator();
				while(iter.hasNext()){
					errorMsg = errorMsg+", "+iter.next();
				}
				throw new ServiceBeanException(errorMsg);
			}
			// Name uniqueness check.
			if(userPermissionTypeDao.verifyUnique("name", userPermissionType.getName(), null)){
				// Create the entry in database.
				userPermissionType = userPermissionTypeDao.create(userPermissionType);
				log.info("The new user permission type created with ID : "+userPermissionType.getId().longValue());
				return userPermissionType;
			}
			else{
				// Name already exists.
				throw new ServiceBeanException(UserManagementErrorMessage.USER_PERMISSION_TYPE_CREATE_DUPLICATE_NAME_EXCEPTION);
			}
		}
		catch(DAOException ex){
			log.error(UserManagementErrorMessage.USER_PERMISSION_TYPE_CREATE_EXCEPTION, ex);
			throw new EJBException(ex);
		}
	}
}
